<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1：0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // ===========================================================================
    // 变量
    // var：
    // 1：有变量声明提升
    // console.log(a);//undefined
    // 2.可以重复声明
    // var a = 1;
    // var a = 2;
    // console.log(a);//2

    // 3.没有块级作用域
    // var b = 1;
    // {
    //     var c = 2;
    // }
    // console.log(c);//2

    // ---------------------------------------------------------------------------
    // let：
    // 1.没有变量声明提升
    // console.log(a);//Cannot access 'a' before initialization
    // 2.不能重复声明
    // let a = 1;//Identifier 'a' has already been declared
    // let a = 2;  //Identifier 'a' has already been declared
    // console.log(a);

    // 3.有块级作用域
    // let b = 1;
    // {
    //     let c = 2;
    // }
    // console.log(c);//c is not defined


    // ---------------------------------------------------------------------------
    // const:
    // 1.没有变量声明提升
    // console.log(a);
    // 2.不能重复声明
    // const a ='hello';//Identifier 'a' has already been declared
    // const a ='hi';//Identifier 'a' has already been declared

    // 3.有块级作用域
    // {
    //     const c = 'noHi'
    // }
    // console.log(c);

    // 4.声明后必须初始化
    // const age; //Missing initializer in const declaration
    // const age =18;
    // 5.声明后不能修改变量的值
    // age = 19;//Assignment to constant variable



    // ---------------------------------------------------------------------------
    // 面试题
    // var：声明变量，有变量声明提升，可以重复声明，没有块级作用域
    // let：声明变量，没有变量声明提升，不可以重复声明，有块级作用域
    // const：声明常量，没有变量声明提升，不可以重复声明，有块级作用域。无法修改，声明时必须要初始化

    // 1.暂时性死区：
    // 使用let或const声明的变量，在声明之前不能使用，即使父级作用域里有同名的变量
    // 解决方法：使用let和const声明变量后再使用
    // var a =1;
    // {
    //     console.log(a);
    //     let a = 2
    // }
    

    // 2.const声明常量
    // 如果常量是引用类型，可以修改内部的数据，但是不能重新赋值
    // const b = {
    //     name: 'jay',
    // }
    // // 可以修改内部的数据
    // b.name = 'joLin'
    // console.log(b);
    // // 不能重新赋值
    // b = {
    //     name: 'jj',
    // }
    // console.log(b);//Assignment to constant variable






    // ===========================================================================
    // 解构赋值
    // 按照一定的模式从数组或者对象中直接把数据取出来，赋值给相应的变量，把结构解散重构然后赋值

    // ---------------------------------------------------------------------------
    // 数组：本质上是一个有序的列表
    // var a = [1, 2, 3];

    // 左右两边都是数组，左边数组里的变量和右边数组里的元素位置要对应
    // var [a, b, c] = [1, 2, 3]
    // console.log(a, b, c);//1 2 3

    // 可以嵌套
    // var [a, [[b], c]] = [1, [[2], 3]]
    // console.log(a, b, c);

    // 可以忽略
    // var [, b,] = [1, 2, 3]
    // console.log(b);//2

    // 不完全解构
    // var [a = 3, b] = []
    // console.log(a, b);//3 , undefined

    // 剩余运算符
    // var [a, ...b] = [1, 2, 3,]
    // console.log(a, b);//1 , [2,3]

    // 字符串
    // var [a, b] = 'hi'
    // console.log(a, b);//h , i

    // 解构默认值
    // var [a = 3 ] =[undefined]
    // console.log(a);//3
    //当解构模式有匹配结果，且匹配结果是 undefined 时，会触发默认值作为返回结果
    // 没有参数
    // var [a = 3, b = a] = [];
    // console.log(a, b);//3 , 3
    // // 一个参数
    // var [a = 3, b = a] = [1];
    // console.log(a, b);//1 , 1
    // // 两个参数
    // var [a = 3, b = a] = [1, 2];
    // console.log(a, b);//1 , 2



    // ---------------------------------------------------------------------------
    // 对象：本质上就是一个无序列表
    // 模式：左右变量都是对象，解构出来的属性名和左侧赋值的变量名要一致
    // var a = {
    //     name: 'jay',
    //     age: 18,
    //     num: {
    //         music: 1000,
    //         girl: 3
    //     }
    // }

    //基本
    // let { foo, bar } = { foo: 'aaa', bar: 'bbb' };// foo = 'aaa', bar = 'bbb'
    // console.log(foo, bar);
    // let { baz: foo } = { baz: 'ddd' };// foo = 'ddd'
    // console.log(foo);


    //可嵌套
    // let obj = { p: ['hello', { y: 'world' }] };
    // let { p: [x, { y }] } = obj;
    // console.log(x,y);// x = 'hello' ,y = 'world'

    //可忽略
    // let obj = { p: ['hello', { y: 'world' }] };
    // let { p: [x, { }] } = obj;// x = 'hello'

    //不完全解构
    // let obj = { p: [{ y: 'world' }] };
    // let { p: [{ y }, x] } = obj;
    // x = undefined
    // y = 'world'


    //剩余运算符
    // let { a, b, ...rest } = { a: 10, b: 20, c: 30, d: 40 };
    // a = 10
    // b = 20
    // rest = {c: 30, d: 40}

    //解构默认值
    // let { a = 10, b = 5 } = { a: 3 };
    // a = 3; b = 5;
    // let { a: aa = 10, b: bb = 5 } = { a: 3 };
    // aa = 3; bb = 5;





    // ---------------------------------------------------------------------------
    // 函数：基本上是把数组的解构赋值和对象的解构赋值结合起来使用
    // function fn({ name, age, hobby: [a, b, c] }) {
    //     console.log(`我叫${name}我今年${age}我的爱好是${a}、${b}、${c}`);
    // }
    // fn({
    //     name: 'jay',
    //     age: 18,
    //     hobby: ['music', 'b', 'c']
    // })





    // ===========================================================================
    // 模版字符串
    // 字符串拼接
    // var a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'];
    // console.log('数组中元素有1：' + a[0] + '，2：' + a[1] + '，3：' + a[2] + '，4：' + a[3] + '，5：' + a[4] + '，6：' + a[5] + '，7：' + a[6] + '，8：' + a[7] + '，9：' + a[8] + '');
    // 模版字符串
    // console.log(
    //     `
    //     数组中元素有1：${a[0]}
    //     2：${a[1]}
    //     3：${a[2]}
    //     4：${a[3]}
    //     5：${a[4]}
    //     6：${a[5]}
    //     7：${a[6]}
    //     8：${a[7]}
    //     9：${a[8]}
    //     `
    // );


    // ===========================================================================
    // 字符串新增方法


    // includes    startsWith       endsWith
    // var a = 'jay and joLin';
    // 检查字符串是否包含某个字符
    // console.log(a.includes('o'));//true
    // 检查字符串是否头部是某个字符
    // console.log(a.startsWith('j'));//true
    // 检查字符串是否尾部是某个字符
    // console.log(a.endsWith('n'));//true


    // repeat
    // 重复指定次数返回
    // console.log(a.repeat(2));//jay and joLinjay and joLin


    // padStart   padEnd
    // 第一个参数是检测数组长度，第二个参数是要补全的字符
    // // 返回新的字符串，表示用参数字符串从头部补全原字符
    // var a = '1';
    // console.log(a.padStart(2, '0'));//01
    // // 返回新的字符串，表示用参数字符串从尾部补全原字符
    // var a = '1';
    // console.log(a.padEnd(2, '0'));//10


    




</script>

</html>